
Imports System.Text

Public Class memblock(Of valueT)
    Implements ICloneable, IComparable

    Private data() As valueT

    Public Function availableIndex(ByVal index As Int64) As Boolean
        Return index >= 0 And index < size()
    End Function

    Public Property size() As Int64
        Get
            If data Is Nothing Then
                Return 0
            Else
                Return data.Length
            End If
        End Get
        Set(ByVal value As Int64)
            If data Is Nothing OrElse data.Length() = 0 OrElse value = 0 Then
                ReDim data(value - 1)
            ElseIf data.Length() <> value Then
                ReDim Preserve data(value - 1)
            End If
        End Set
    End Property

    Public Sub New()
        clear()
    End Sub

    Public Sub New(ByVal value As memblock(Of valueT))
        copy(value)
    End Sub

    Public Sub New(ByVal value() As valueT)
        copy(value)
    End Sub

    Public Sub New(ByVal value() As valueT, ByVal index As Int64)
        copy(value, index)
    End Sub

    Public Sub New(ByVal value() As valueT, ByVal index As Int64, ByVal length As Int64)
        copy(value, index, length)
    End Sub

    Public Sub New(ByVal value As valueT)
        copy(value)
    End Sub

    Public Sub attach(ByVal value() As valueT)
        clear()
        data = value
    End Sub

    Public Sub cut(ByVal index As Int64, Optional ByVal len As Int64 = npos)
        If len = npos Then
            len = size() - index
        End If
        memmove(data, 0, data, index, len)
        size() = len
    End Sub

    Public Sub copy(ByVal value() As valueT, ByVal index As Int64)
        If Not value Is Nothing Then
            copy(value, index, value.Length() - index)
        End If
    End Sub

    Public Sub copy(ByVal value() As valueT, ByVal index As Int64, ByVal length As Int64)
        If Not value Is Nothing Then
            debugassert(index + length <= value.Length, "value() does not have enough size, ignore copy function.")
            ReDim data(length - 1)
            memcpy(data, 0, value, index, length)
        End If
    End Sub

    Public Sub copy(ByVal value As valueT)
        Dim internal(0) As valueT
        internal(0) = value
        copy(internal)
    End Sub

    Public Sub copy(ByVal value() As valueT)
        If Not value Is Nothing Then
            copy(value, 0, value.Length())
        End If
    End Sub

    Public Sub copy(ByVal value As memblock(Of valueT))
        If Not value Is Nothing Then
            copy(value.data)
        End If
    End Sub

    Public Sub clear()
        [erase](data)
    End Sub

    Protected Sub append(ByVal left As memblock(Of valueT), ByVal right As memblock(Of valueT))
        append(left)
        append(right)
    End Sub

    Public Sub append(ByVal right As memblock(Of valueT))
        If Not right Is Nothing Then
            append(+right)
        End If
    End Sub

    Public Sub append(ByVal right As valueT())
        If Not right Is Nothing AndAlso right.Length() > 0 Then
            Dim oldlen As Int64 = size()
            size += right.Length()
            memcpy(data, oldlen, right, 0, right.Length())
        End If
    End Sub

    Public Shared Operator +(ByVal left As memblock(Of valueT) _
                             , ByVal right As memblock(Of valueT)) As memblock(Of valueT)
        Dim rtn As memblock(Of valueT) = Nothing
        rtn = New memblock(Of valueT)()
        rtn.append(left, right)

        Return rtn
    End Operator

#If RETIRED Then
    Public Shared Operator +(ByVal left As memblock(Of valueT), ByVal right() As valueT) As memblock(Of valueT)
        Return left + New memblock(Of valueT)(right)
    End Operator

    Public Shared Operator +(ByVal left() As valueT, ByVal right As memblock(Of valueT)) As memblock(Of valueT)
        Return New memblock(Of valueT)(left) + right
    End Operator

    Public Shared Operator +(ByVal left As memblock(Of valueT), ByVal right As valueT) As memblock(Of valueT)
        Return left + New memblock(Of valueT)(right)
    End Operator

    Public Shared Operator +(ByVal left As valueT, ByVal right As memblock(Of valueT)) As memblock(Of valueT)
        Return New memblock(Of valueT)(left) + right
    End Operator
#End If

    Public Shared Widening Operator CType(ByVal left As memblock(Of valueT)) As valueT()
        Return +left
    End Operator

    Public Shared Operator +(ByVal left As memblock(Of valueT)) As valueT()
        If Not left Is Nothing Then
            Return left.data
        Else
            Return Nothing
        End If
    End Operator

    Public Shared Widening Operator CType(ByVal left As valueT()) As memblock(Of valueT)
        If left Is Nothing OrElse left.Length = 0 Then
            Return Nothing
        Else
            Return New memblock(Of valueT)(left)
        End If
    End Operator

    Public Shared Widening Operator CType(ByVal left As valueT) As memblock(Of valueT)
        Return New memblock(Of valueT)(left)
    End Operator

    Default Public Property at(ByVal index As Int64) As valueT
        Get
            If availableIndex(index) Then
                Return data(index)
            Else
                Return Nothing
            End If
        End Get
        Set(ByVal value As valueT)
            If availableIndex(index) Then
                _interfaceOperations.copy(data(index), value)
            End If
        End Set
    End Property

    Public Overridable Function Clone() As Object Implements System.ICloneable.Clone
        Dim obj As memblock(Of valueT) = Nothing
        'also make it safe as the change in bytes
        If Not Me Is Nothing Then
            obj = New memblock(Of valueT)(Me)
        End If

        Return obj
    End Function

    Public Shared Operator =(ByVal this As memblock(Of valueT), ByVal that As memblock(Of valueT)) As Boolean
        If this Is Nothing AndAlso that Is Nothing Then
            Return True
        ElseIf this Is Nothing OrElse that Is Nothing Then
            Return False
        Else
            Return compare(this, that) = 0
        End If
    End Operator

    Public Shared Operator <>(ByVal this As memblock(Of valueT), ByVal that As memblock(Of valueT)) As Boolean
        Return Not this = that
    End Operator

    Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
        Dim right As memblock(Of valueT) = Nothing
        right = convertor.cast(Of memblock(Of valueT))(obj)

        If size() <> right.size() Then
            Return size() - right.size()
        Else
#If Not (PocketPC OrElse Smartphone) Then
            Return memcmp(data, 0, right.data, 0, size())
#Else
            Return -1
#End If
        End If
    End Function

    Public Overrides Function ToString() As String
        Dim sb As StringBuilder = Nothing
        sb = New StringBuilder()
        sb.Append("(") _
          .Append(size()) _
          .Append(")") _
          .Append("{")
        For i As Int64 = 0 To size() - 1
            sb.Append(Convert.ToString(at(i)))
            If i < size() - 1 Then
                sb.Append(", ")
            End If
        Next
        sb.Append("}")
        Return Convert.ToString(sb)
    End Function
End Class
